package com.bolt.admin.module.sys.service;

import com.bolt.admin.module.sys.dto.OrgDTO;
import com.bolt.admin.module.sys.dto.converter.OrgConverter;
import com.bolt.admin.module.sys.entity.AreaEntity;
import com.bolt.admin.module.sys.entity.OrgEntity;
import com.bolt.admin.module.sys.repository.OrgRepository;
import com.bolt.common.reflect.ReflectionUtil;
import com.bolt.common.utils.StrUtil;
import com.bolt.core.view.components.FormItem;
import com.bolt.core.view.components.ListDataLoad;
import com.bolt.support.base.service.BaseTreeService;
import com.bolt.support.spring.jpa.filter.GroupPropertyFilter;
import com.bolt.support.spring.jpa.filter.LambdaFilterBuilder;
import com.bolt.support.spring.jpa.jpql.Clauses;
import com.bolt.support.spring.jpa.repository.BasicJpaRepository;
import com.bolt.support.spring.jpa.specification.QueryHelp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Auto Generate Javadoc
 *
 * @author 米超
 *         日期:2018-02-27 14:20:36
 *         机构信息
 **/
@Service
@Transactional(readOnly = true,rollbackFor = Exception.class)
public class OrgService extends BaseTreeService <OrgEntity, String> implements ListDataLoad {

    @Autowired
    private OrgRepository orgRepository;

    @Autowired
    private AreaService areaService;


    @Override
    protected BasicJpaRepository <OrgEntity, String> getRepository() {
        return orgRepository;
    }

    @Transactional(rollbackFor = Exception.class)
    public OrgEntity saveOrUpdate(OrgDTO orgDTO) {
        OrgEntity entity = OrgConverter.toEntity(orgDTO);
        AreaEntity areaEntity = areaService.findByAreaCode(orgDTO.getAreaCode());
        entity.setAreaInfo(areaEntity);
        if(entity.isNew()){
            String code = nextCode(entity,"code");
            entity.setCode(code);
        }
        save(entity);
        return entity;
    }

    public OrgDTO getOne(String id){
        return jpaQueryFactory.select(OrgDTO.class,
                Clauses.of(OrgEntity::getId),
                Clauses.of(OrgEntity::getName),
                Clauses.of(OrgEntity::getAreaCode),
                Clauses.of(OrgEntity::getCode),
                Clauses.of(OrgEntity::getTel),
                Clauses.of(OrgEntity::getAddress),
                Clauses.of(OrgEntity::getRemarks),
                Clauses.of(OrgEntity::getZipCode),
                Clauses.of(OrgEntity::getEmail),
                Clauses.of(OrgEntity::getVersionNO),
                Clauses.of(OrgEntity::getPid),
                Clauses.of(OrgEntity::getEnabled),
                Clauses.of(AreaEntity::getName).as("areaName")
        ).from(Clauses.of(OrgEntity.class))
                .innerJoin(Clauses.of(AreaEntity.class))
                .on(Clauses.of(OrgEntity::getAreaCode),Clauses.of(AreaEntity::getAreaCode))
                .where(Clauses.of().eq(Clauses.of(OrgEntity::getId),id))
                .fetchFirst();
    }

    public List<OrgDTO> findOrg(OrgDTO orgDTO){
        return jpaQueryFactory.select(OrgDTO.class,
                Clauses.of(OrgEntity::getId),
                Clauses.of(OrgEntity::getName),
                Clauses.of(OrgEntity::getAreaCode),
                Clauses.of(OrgEntity::getCode),
                Clauses.of(OrgEntity::getTel),
                Clauses.of(OrgEntity::getAddress),
                Clauses.of(OrgEntity::getRemarks),
                Clauses.of(OrgEntity::getZipCode),
                Clauses.of(OrgEntity::getEmail),
                Clauses.of(OrgEntity::getVersionNO),
                Clauses.of(OrgEntity::getPid),
                Clauses.of(OrgEntity::getEnabled),
                Clauses.of(AreaEntity::getName).as("areaName")
             ).from(Clauses.of(OrgEntity.class))
                .innerJoin(Clauses.of(AreaEntity.class))
                .on(Clauses.of(OrgEntity::getAreaCode),Clauses.of(AreaEntity::getAreaCode))
                .where(QueryHelp.getOperationClause(orgDTO))
                .fetch();
    }

    @Override
    public Map <String, String> load(FormItem item, Map   param) {
        String field = "id";
        if (param.containsKey("key")) {
            field = (String)param.get("key");
        }
        Map <String, String> r = new LinkedHashMap <>();
        List <OrgEntity> tree = orgRepository.findAll(Sort.by(Sort.Direction.ASC,"orderRank"));
        r.put("", "无上级");
        for (OrgEntity org : tree) {
            List <String> join = new ArrayList <>();
            for (int i = 0; i < org.getLevel(); i++) {
                join.add("&#160;&#160");
            }
            join.add(org.getName());
            Object key = ReflectionUtil.getFieldValue(org, field);
            r.put(String.valueOf(key), StrUtil.join(join, ""));
        }
        return r;
    }


    public static void main(String[] args) {
        LambdaFilterBuilder<OrgEntity> filterBuilder = new LambdaFilterBuilder <>();
        filterBuilder.eq(OrgEntity::getEmail,"@").eq(OrgEntity::getId,"123123");
        GroupPropertyFilter filter = filterBuilder.build();
        System.out.println(filter);
    }
}
